﻿namespace Snipps.ViewModels.Filters
{
    using System;
    using System.Collections.Generic;

    using Snipps.Core;
    using Snipps.Core.Entities;
    using Snipps.Infrastructure.Services;

    public class ProgrammingLangFilterViewModel : FilterViewModelBase
    {
        private readonly ISnippetsDataContext _snippetsDataContext;

        private readonly IThreadingService _threadingService;

        private ProgrammingLang _currentProgrammingLang;

        public ProgrammingLangFilterViewModel(ISnippetsDataContext snippetsDataContext, IThreadingService threadingService)
        {
            _snippetsDataContext = snippetsDataContext;
            _threadingService = threadingService;

            CompletionList.IsReadOnly = true;
        }

        public ProgrammingLang CurrentProgrammingLang
        {
            get
            {
                return _currentProgrammingLang;
            }

            set
            {
                SetProperty(ref _currentProgrammingLang, value, "CurrentProgrammingLang", OnCurrentProgrammingLangChanged);
            }
        }

        private void OnCurrentProgrammingLangChanged()
        {
            if (CurrentProgrammingLang != null)
            {
                FilterText = CurrentProgrammingLang.Name;
            }
        }

        public override void Cleanup()
        {
            _filterText = string.Empty;
            _currentProgrammingLang = null;
            base.Cleanup();
        }

        protected override void OnIsActiveChanged()
        {
            base.OnIsActiveChanged();

            if (IsActive)
            {
                StartFiltering();
            }

            if (CurrentProgrammingLang == null)
            {
                if (!string.IsNullOrEmpty(FilterText))
                {
                    FilterText = string.Empty;
                }

                return;
            }

            if (CurrentProgrammingLang.Name != FilterText)
            {
                if (FilterText.Length > 0)
                {
                    FilterText = CurrentProgrammingLang.Name;
                }
                else
                {
                    FilterText = string.Empty;
                    CurrentProgrammingLang = null;
                }
            }
        }

        public override void StartFiltering()
        {
            if (IsBusy)
            {
                return;
            }

            base.StartFiltering();
            if (FilterText == null)
            {
                FilterText = string.Empty;
            }

            Func<IList<ProgrammingLang>> f = () => _snippetsDataContext.FilterProgrammingLangs(FilterText);
            cancelFilteringAction = _threadingService.QueueExecution(f, GetProgrammingLangAsyncEnd, ExceptionCallback);
        }

        private void ExceptionCallback(Exception obj)
        {
        }

        private void GetProgrammingLangAsyncEnd(IList<ProgrammingLang> programmingLangs)
        {
            CompletionList.ClearFilteredItems();

            _threadingService.QueueExecution(
                () =>
                    {
                        foreach (var programmingLang in programmingLangs)
                        {
                            CompletionList.FilteredItems.Add(programmingLang);
                        }
                    }, 
                () =>
                    {
                        SelectBestMatchingItem();
                        IsBusy = false;
                    });
        }
    }
}